// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#include "coin2/exchange/base/order/grpc_trade_client_mgr.h"

#include "coin/proto/coin_order_enums.pb.h"
#include "coin2/exchange/uniswap/api_order/grpc/grpc_trade_client.h"

namespace coin2::exchange::base::order {

bool GrpcTradeClientMgr::Enabled(const MarketExchangeApi& mea) {
  using ClientProtocol = coin::proto::OrderGatewayClientProtocol;

  std::ifstream ifs("data/coin2/order/og_info.json");
  nlohmann::json jf = nlohmann::json::parse(ifs);
  if (jf.find(mea.String()) == jf.end()) {
    return false;
  }
  auto data = jf[mea.String()];
  if (data.find("order_gateway_client_protocol") == data.end()) {
    return false;
  }
  for (auto protocol_str : data["order_gateway_client_protocol"]) {
    ClientProtocol protocol;
    CHECK(OrderGatewayClientProtocol_Parse(protocol_str, &protocol))
        << "unknow protocol type [" << protocol_str << "] for mea [" << mea.String() << "]";
    if (protocol == ClientProtocol::GRPC) {
      return true;
    }
  }
  return false;
}

auto GrpcTradeClientMgr::Create(
    const MarketExchangeApi& mea,
    const OrderConnectionConfig& ord_conn_cfg) -> GrpcTradeClientPtr {
  auto exchange = base::market::ExchangeTypeToString(mea.exchange);

  bool enabled = false;
  if (ord_conn_cfg.has_use_grpc()) {
    enabled = ord_conn_cfg.use_grpc();
  } else {
    enabled = Enabled(mea);
  }
  if (!enabled) {
    LOG(INFO) << "grpc trade api disabled for exchange [" << exchange << "]";
    return nullptr;
  }

  if ("Uniswap" == exchange) {
    using GrpcTradeClient = coin2::exchange::uniswap::api_order::grpc::UniswapGrpcTradeClient;
    return std::make_unique<GrpcTradeClient>(mea, ord_conn_cfg, true);
  } else {
    LOG(ERROR) << "unsupported exhange: [" << exchange << "]";
    return nullptr;
  }
}

}  // namespace coin2::exchange::base::order
